home *** CD-ROM | disk | FTP | other *** search
-
- /*
-
- WART
-
- Wart is a program that implements a small subset of the Unix 'lex'
- lexical analyzer generator. Unlike lex, wart may be distributed without
- requirement for a Unix license. Wart was written at the Columbia University
- Center of Computing Activities to facilitate development of Unix Kermit.
-
- Wart is intended for production of state table switchers. It allows a
- set of states to be defined, along with a function for getting input. The
- performs actions and switches states based on the current state and the
- input.
-
- The following short program demonstrates some of the capabilities and
- limitations of Wart. The program accepts from the command line a binary
- number, preceded by an optional minus sign, and optionally containing a
- fractional part. It prints the decimal equivalent.
-
- #include <stdio.h>
-
- int state, s = 1, m = 0, d;
- float f;
- char *b;
-
- %states sign mantissa fraction /* Declare wart states */
-
- %% /* Begin state table */
- <sign>- { s = -1; BEGIN mantissa; } /* Look for sign */
- <sign>0 { m = 0; BEGIN mantissa; } /* Got digit, start mantissa */
- <sign>1 { m = 1; BEGIN mantissa; }
- <sign>. { fatal("bad input "); } /* Detect bad format */
- <mantissa>0 { m *= 2; } /* Accumulate mantissa */
- <mantissa>1 { m = 2 * m + 1; }
- <mantissa>$ { printf("%d\n", s * m); return; }
- <mantissa>. { f = 0.0; d = 1; BEGIN fraction; } /* Start fraction */
- <fraction>0 { d *= 2; } /* Accumulate fraction */
- <fraction>1 { d *= 2; f += 1.0 / d; }
- <fraction>$ { printf("%f\n", s * (m + f) ); return; }
- <fraction>. { fatal("bad input"); }
- %%
-
- input() { /* Define input() function */
- int x;
- return(((x = *b++) == '\0') ? '$' : x );
- }
-
- fatal(s) char *s; { /* Error exit */
- fprintf(stderr,"fatal - %s\n",s);
- exit(1);
- }
-
- main(argc,argv) int argc; char **argv; { /* Main program */
- if (argc < 1) exit(1);
- b = *++argv;
- state = sign; /* Initialize state */
- wart(); /* Invoke state switcher */
- exit(0); /* Done */
- }
-
- The wart program accepts as input a C program containing lines that start
- with "%" or sections delimited by "%%". The directive "%states" declares
- the program's states. The section enclosed by "%%" markers is the state
- table, with entries of the form
-
- <state>X { action }
-
- which read as "if in state <state> with input X perform { action }"
-
- The optional <state> field tells the current state or state the program must
- be in to perform the indicated action. If no state is specified, then it
- means the action will be performed regardless of the current state. If more
- than one state is specifed, then the action will be performed in any of the
- listed states. Multiple states are separated by commas.
-
- The required input field consists of a single literal character. When in
- the indicated state, if the input is the specified character, then the
- associated action will be performed. The character '.' matches any input
- character. No pattern matching or range notation is provided. The input
- character is obtained from the input() function, which you must define. It
- should be alphanumeric, or else one of the characters ".% -$@" (quotes not
- included). Note that the program above recognize the binary point '.'
- through a ruse.
-
- The action is a series of zero or more C language statements, enclosed in
- curly braces.
-
- The BEGIN macro is defined simply to be "state = ", as in lex.
-
- The wart() function is generated by the wart program based on the state
- declarations and the state transition table. It loops through calls to
- input(), using the result to index into a big case statement it has created
- from the state table.
-
- Wart is invoked as follows:
-
- wart
-
- Input from stdin, output to stdout
-
- wart fn1
-
- Input from fn1, output to stdout
-
- wart fn1 fn2
-
- Input from fn1, output to fn2. Example: wart a.w a.c
-
- Wart programs have the conventional filetype '.w'.
- (18 Feb 85)
- */